import { PackageSearch, Lock, Unlock } from "lucide-react";
import React, { useState, useEffect } from "react";
import { BoxComparison } from "./components/BoxComparison";
import { canBoxFit } from "./utils/boxFit";
import { indexedDBManager } from "./utils/indexedDB";

interface ModelAttributes {
  name: string;
  realLength: number;
  realWidth: number;
  realHeight: number;
}

/**
 *  坐标问题使用宽，高数据与显示有点不一致
 * @returns
 */
function App() {
  const [itemDimensions, setItemDimensions] = useState({
    length: 0,
    width: 0,
    height: 0,
  });

  const [containerDimensions, setContainerDimensions] = useState({
    length: 6,
    width: 6,
    height: 6,
  });

  const [error, setError] = useState<string>("");
  const [result, setResult] = useState<boolean | null>(null);
  const [showAnimation, setShowAnimation] = useState(false);
  const [itemModelUrl, setItemModelUrl] = useState<string | null>(null);
  const [selectedPresetModel, setSelectedPresetModel] = useState<string>("");
  const [localFile, setLocalFile] = useState<File | null>(null);
  const [showDimensions, setShowDimensions] = useState(false);
  const [isLocked, setIsLocked] = useState(false);
  const [isLocking, setIsLocking] = useState(false);

  // 检查 IndexedDB 中的锁定文件
  useEffect(() => {
    const checkLockedFile = async () => {
      try {
        const file = await indexedDBManager.getFile();
        if (file) {
          const url = URL.createObjectURL(file);
          setLocalFile(file);
          setItemModelUrl(url);
          setIsLocked(true);
        }
      } catch (error) {
        console.error('Error loading locked file:', error);
        setError('加载锁定文件失败，请刷新页面重试');
      }
    };

    checkLockedFile();

    // 清理函数
    return () => {
      if (itemModelUrl) {
        URL.revokeObjectURL(itemModelUrl);
      }
    };
  }, []);

  const handleLockToggle = async () => {
    if (isLocking) return; // 防止重复点击
    
    setIsLocking(true);
    try {
      if (isLocked) {
        // 解锁
        await indexedDBManager.removeFile();
        if (itemModelUrl) {
          URL.revokeObjectURL(itemModelUrl);
        }
        setItemModelUrl(null);
        setLocalFile(null);
        setIsLocked(false);
      } else if (itemModelUrl && localFile) {
        // 锁定
        await indexedDBManager.saveFile(localFile);
        setIsLocked(true);
      }
    } catch (error) {
      console.error('Error toggling lock:', error);
      setError(isLocked ? '解锁失败，请重试' : '锁定失败，请重试');
    } finally {
      setIsLocking(false);
    }
  };

  const handleCustomAttributesLoad = (attributes: ModelAttributes) => {
    // 校验数据
    if (attributes.realLength === 0 || attributes.realWidth === 0 || attributes.realHeight === 0) {
      setError("请选择正确的模型");
    }
    // 从模型属性中读取实际尺寸，并保留2位小数
    setItemDimensions({
      length: Number(attributes.realLength.toFixed(2)),
      height: Number(attributes.realWidth.toFixed(2)),
      width: Number(attributes.realHeight.toFixed(2)),
    });
  };

  const validateInput = (value: string): number | null => {
    if (value === '') return 0; // 允许空值
    const num = parseFloat(value);
    if (isNaN(num)) return null;
    if (num < 0) return null; // 只拦截负数
    return num;
  };

  const handleCheck = () => {
    // 检查是否已选择模型
    if (!itemModelUrl) {
      setError("请先选择一个学习小组");
      return;
    }

    // 检查实物尺寸是否为0
    if (itemDimensions.length === 0 || itemDimensions.width === 0 || itemDimensions.height === 0) {
      setError("实物尺寸不能为0,请重新选择文件");
      return;
    }

    // 检查包装盒尺寸是否为0或未填写
    if (containerDimensions.length === 0 || containerDimensions.width === 0 || containerDimensions.height === 0) {
      setError("请输入完整的包装盒尺寸，且不能为0");
      return;
    }

    const itemArray: [number, number, number] = [
      itemDimensions.length,
      itemDimensions.width,
      itemDimensions.height,
    ];

    const containerArray: [number, number, number] = [
      containerDimensions.length,
      containerDimensions.width,
      containerDimensions.height,
    ];

    const fits = canBoxFit(itemArray, containerArray);
    setResult(fits);
    setShowAnimation(true);
    setError(""); // 清除错误信息
  };

  const handleReset = () => {
    // 重置所有状态
    setShowAnimation(false);
    setResult(null);
    setError("");
  };

  const handleInputChange = (
    e: React.ChangeEvent<HTMLInputElement>,
    type: "item" | "container",
    dimension: "length" | "width" | "height"
  ) => {
    const inputValue = e.target.value;
    
    // 清除之前的错误（如果有）
    if (error) {
      setError("");
    }

    // 如果是空字符串，直接更新状态
    if (inputValue === '') {
      if (type === "container") {
        setContainerDimensions((prev) => ({ ...prev, [dimension]: 0 }));
      }
      return;
    }

    // 验证数值输入
    const value = validateInput(inputValue);
    if (value === null) {
      setError("请输入有效的数字");
      return;
    }

    setShowAnimation(false);

    if (type === "item") {
      setItemDimensions((prev) => ({ ...prev, [dimension]: value }));
    } else {
      setContainerDimensions((prev) => ({ ...prev, [dimension]: value }));
    }
  };

  const handleLocalFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (file) {
      if (file.name.toLowerCase().endsWith('.glb')) {
        // 重置所有状态
        setShowAnimation(false);
        setResult(null);
        setError("");
        setLocalFile(file);
        setSelectedPresetModel(""); // 清除预设模型选择
        setItemModelUrl(URL.createObjectURL(file));
        setShowDimensions(false); // 重置尺寸显示状态
      } else {
        setError("请选择 .glb 格式的文件");
        setLocalFile(null);
        setItemModelUrl(null);
      }
    }
  };

  const handleToggleDimensions = () => {
    setShowDimensions((prev) => !prev);
  };

  const handleAnimationComplete = () => {
    // This function is no longer used in the new version
  };

  const dimensionStyle = showDimensions ? 'opacity-100 max-h-[200px]' : 'opacity-0 max-h-0 overflow-hidden';
  const transitionStyle = showDimensions ? 'transition-all duration-300 ease-in-out' : '';

  return (
    <div className="bg-gray-100 p-4 md:p-6 lg:p-8 min-h-screen">
      <div className="max-w-full h-[90dvh] flex flex-col justify-start">
        <h1 className="text-2xl md:text-3xl font-bold text-center text-gray-800 mb-6 md:mb-8 mt-2 md:mt-4">
          3D盒子装箱演示
        </h1>

        <div className="flex flex-1 flex-col md:flex-row gap-4 md:gap-6">
          <div className="flex flex-col gap-4 w-full md:w-[340px]">
            <div className="bg-white p-4 xl:p-6 rounded-lg shadow-md">
              <div className="flex items-center justify-between mb-4">
                <h2 className="text-lg md:text-xl font-semibold">
                  实物尺寸
                  <small className="font-normal ml-1">(单位：cm)</small>
                </h2>
                <button
                  onClick={handleToggleDimensions}
                  className="px-3 py-1 text-sm text-gray-700 bg-gray-200 rounded-md hover:bg-gray-300 transition-colors"
                >
                  {showDimensions ? '隐藏尺寸' : '显示尺寸'}
                </button>
              </div>
              <div className="p-2 md:p-4 space-y-6">
                {/* 尺寸展示 */}
                <div className={`${transitionStyle} ${dimensionStyle}`}>
                  <div className="grid grid-cols-3 gap-3">
                    <div className="flex flex-col items-center p-3 bg-blue-50 rounded-lg border border-blue-100">
                      <span className="text-sm font-medium text-blue-600 mb-1">长度</span>
                      <div className="flex items-baseline">
                        <span className="text-lg font-semibold text-blue-700">{itemDimensions.length}</span>
                      </div>
                    </div>
                    <div className="flex flex-col items-center p-3 bg-blue-50 rounded-lg border border-blue-100">
                      <span className="text-sm font-medium text-blue-600 mb-1">宽度</span>
                      <div className="flex items-baseline">
                        <span className="text-lg font-semibold text-blue-700">{itemDimensions.height}</span>
                      </div>
                    </div>
                    <div className="flex flex-col items-center p-3 bg-blue-50 rounded-lg border border-blue-100">
                      <span className="text-sm font-medium text-blue-600 mb-1">高度</span>
                      <div className="flex items-baseline">
                        <span className="text-lg font-semibold text-blue-700">{itemDimensions.width}</span>
                      </div>
                    </div>
                  </div>
                </div>

                {/* 文件上传 */}
                <div>
                  <div className="flex items-center justify-between mb-2">
                    <label className="block text-sm font-medium text-gray-600">
                      学习小组
                    </label>
                    {(itemModelUrl || localFile) && (
                      <button
                        onClick={handleLockToggle}
                        disabled={isLocking}
                        className={`p-1.5 rounded-lg transition-colors ${
                          isLocking 
                            ? 'opacity-50 cursor-not-allowed' 
                            : isLocked 
                              ? 'bg-amber-100 text-amber-600 hover:bg-amber-200' 
                              : 'bg-gray-100 text-gray-600 hover:bg-gray-200'
                        }`}
                        title={isLocked ? '解锁文件' : '锁定文件'}
                      >
                        {isLocked ? (
                          <Lock size={16} strokeWidth={1.5} />
                        ) : (
                          <Unlock size={16} strokeWidth={1.5} />
                        )}
                      </button>
                    )}
                  </div>
                  <div className="mt-1">
                    <input
                      type="file"
                      accept=".glb"
                      onChange={handleLocalFileChange}
                      className="block w-full text-sm text-transparent
                        file:mr-3 file:py-2 file:px-4
                        file:rounded-lg file:border-0
                        file:text-sm file:font-medium
                        file:bg-blue-50 file:text-blue-700
                        hover:file:bg-blue-100
                        focus:outline-none"
                      disabled={isLocked}
                    />
                    {(itemModelUrl || localFile) && (
                      <div className="mt-2 flex items-center gap-2">
                        <span className="block text-sm text-green-600">
                          已选择 {localFile ? localFile.name : selectedPresetModel.replace('.glb', '')}
                        </span>
                        {isLocked && (
                          <span className="text-xs text-amber-600 bg-amber-50 px-2 py-0.5 rounded-full">
                            已锁定
                          </span>
                        )}
                      </div>
                    )}
                  </div>
                </div>
              </div>
            </div>

            <div className="bg-white p-4 xl:p-6 rounded-lg shadow-md">
              <div className="flex items-center gap-2 mb-4">
                <PackageSearch className="w-5 h-5 text-red-500" />
                <h2 className="text-lg md:text-xl font-semibold">
                  包装盒内部尺寸
                  <small className="font-normal ml-1">(单位：cm)</small>
                </h2>
              </div>
              <div className="space-y-4">
                <div>
                  <label className="block text-sm font-medium text-gray-700">
                    长度
                  </label>
                  <input
                    type="number"
                    value={containerDimensions.length || ''}
                    onChange={(e) =>
                      handleInputChange(e, "container", "length")
                    }
                    className="mt-1 h-8 p-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500"
                    step="any"
                  />
                </div>
                <div>
                  <label className="block text-sm font-medium text-gray-700">
                    宽度
                  </label>
                  <input
                    type="number"
                    value={containerDimensions.height || ''}
                    onChange={(e) =>
                      handleInputChange(e, "container", "height")
                    }
                    className="mt-1 h-8 p-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500"
                    step="any"
                  />
                </div>
                <div>
                  <label className="block text-sm font-medium text-gray-700">
                    高度
                  </label>
                  <input
                    type="number"
                    value={containerDimensions.width || ''}
                    onChange={(e) => handleInputChange(e, "container", "width")}
                    className="mt-1 h-8 p-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500"
                    step="any"
                  />
                </div>
              </div>
            </div>
          </div>

          <div className="flex-1 flex flex-col">
            <div className="flex-1 h-[500px] md:h-[600px] lg:h-full rounded-xl overflow-hidden">
              <BoxComparison
                itemDimensions={[
                  itemDimensions.length,
                  itemDimensions.width,
                  itemDimensions.height,
                ]}
                containerDimensions={[
                  containerDimensions.length,
                  containerDimensions.width,
                  containerDimensions.height,
                ]}
                showAnimation={showAnimation}
                fits={result}
                onAnimationComplete={handleAnimationComplete}
                itemModelUrl={itemModelUrl || undefined}
                onReset={handleReset}
                onCustomAttributesLoad={handleCustomAttributesLoad}
                onCheck={handleCheck}
                error={error}
              />
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

export default App;
